﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace HA.ModFlow.Infrastructure
{
    [Serializable]
    public class CellCenterDataSet3d:DataSet3d
    {
        #region 构造函数
        /// <summary>
        /// 注意三维数组的每一个维数的含义  double[ rows  ,  cols  , layers  ] 
        /// </summary>
        /// <param name="data"></param>
        /// <param name="iBound"></param>
        public CellCenterDataSet3d(double[, ,] data,List <int [,]> iBound)
            : base(data.GetLength(0), data.GetLength(1), data.GetLength(2))
        {

            this._datas = data;

            if (iBound == null)
            {
                this._effIBound = new List<int[,]>();

                for (int layer = 0; layer < this.Nlayers ; layer++)
                {
                    int [,] layerCell=new  int[this.Nrows ,this.Ncols ];

                    this._effIBound.Add(layerCell );
                    
                }

            }
            else
            {
                this._effIBound = iBound;
            }
            

            //this.ComputeMinMax();

        }

        public CellCenterDataSet3d(double[, ,] data, List<int[,]> iBound, double invalidValue)
            : base(data.GetLength(0), data.GetLength(1), data.GetLength(2))
        {

            this._datas = data;

            if (iBound == null)
            {
                this._effIBound = new List<int[,]>();

                for (int layer = 0; layer < this.Nlayers; layer++)
                {
                    int[,] layerCell = new int[this.Nrows, this.Ncols];

                    this._effIBound.Add(layerCell);

                }

            }
            else
            {
                this._effIBound = iBound;
            }


            this.InvalidValue = invalidValue;

            //this.ComputeMinMax();

        }


        public CellCenterDataSet3d(int nrows, int ncols, int nlayers)
            : base(nrows, ncols, nlayers)
        {



            _datas = new double[nrows, ncols, nlayers];

            this.MinValue = 0;
            this.MaxValue = 0;



        }


        /// <summary>
        /// 这个方法主要用于直接接收某些特殊类型的数据
        /// </summary>
        public CellCenterDataSet3d(List<double[,]> data, List<int[,]> iBound, int nrows, int ncols, int nlayers)
            : base(nrows, ncols, nlayers)
        {

            _datas = new double[nrows, ncols, nlayers];

            for (int k = 0; k < nlayers; k++)
            {
                for (int i = 0; i < nrows; i++)
                {

                    for (int j = 0; j < ncols; j++)
                    {
                        this._datas[i, j, k] = data[k][i, j];
                        
                    }
                }
                
            }


            this._effIBound = iBound;

            //this.ComputeMinMax();


        }




      




        #endregion



        #region 字段属性


        string _label="0_0_0";
        /// <summary>
        /// 标签   格式： MT3D: 应力期_时间步长_传输步长_时间   ModFlow:应力期_时间步长
        /// </summary>
        public string Label
        {
            get { return _label; }
            set { _label = value; }
        }



        double[, ,] _datas;
        /// <summary>
        /// 核心数据
        /// </summary>
        public double[, ,] Datas
        {
            get { return _datas; }

        }


        List<int[,]> _effIBound;
        /// <summary>
        /// 单元有效性  
        /// </summary>
        public  List<int[,]> EffIBound
        {
            get { return _effIBound; }
            //set { _effIBound = value; }
        }

        /// <summary>
        /// 现取现算
        /// </summary>
        public override double MaxValue
        {
            get
            {
                #region 现取现算方法

                double maxScalar = 0;

                if (this.Nlayers > 0 && this.Nrows > 0 && this.Ncols > 0)
                {
                    maxScalar = double.MinValue;
                }

                if (this._effIBound != null)
                {
                    for (int layer = 0; layer < this.Nlayers; layer++)
                    {
                        for (int row = 0; row < this.Nrows; row++)
                        {
                            for (int col = 0; col < this.Ncols; col++)
                            {
                                if (this._effIBound[layer][row, col] != 0)
                                {
                                    //当单元有效的时候将影响最大最小值

                                    #region 最大值
                                    if (this.Datas[row, col, layer] > maxScalar && Math.Abs(this.Datas[row, col, layer] - this.InvalidValue) > 1e-6)
                                    {
                                        maxScalar = this.Datas[row, col, layer];
                                    }

                                    #endregion

                                }
                            }
                        }
                    }
                }
                else
                {
                    for (int layer = 0; layer < this.Nlayers; layer++)
                    {
                        for (int row = 0; row < this.Nrows; row++)
                        {
                            for (int col = 0; col < this.Ncols; col++)
                            {
                                #region 最大值

                                if (this.Datas[row, col, layer] > maxScalar && Math.Abs(this.Datas[row, col, layer] - this.InvalidValue) > 1e-6)
                                {
                                    maxScalar = this.Datas[row, col, layer];
                                }

                                #endregion
                            }
                        }
                    }
                }

                if ( maxScalar == double.MinValue)
                {
                    maxScalar = 0;
                }

                base.MaxValue = maxScalar;



                return base.MaxValue;


                #endregion

            }
        }

        /// <summary>
        /// 现取现算
        /// </summary>
        public override double MinValue
        {
            get
            {
                #region 现取现算方法

                double minScalar = 0;

                if (this.Nlayers > 0 && this.Nrows > 0 && this.Ncols > 0)
                {
                    minScalar = double.MaxValue;
                }

                if (this._effIBound != null)
                {
                    for (int layer = 0; layer < this.Nlayers; layer++)
                    {
                        for (int row = 0; row < this.Nrows; row++)
                        {
                            for (int col = 0; col < this.Ncols; col++)
                            {
                                if (this._effIBound[layer][row, col] != 0)
                                {
                                    //当单元有效的时候将影响最大最小值

                                    #region 最小值
                                    if (this.Datas[row, col, layer] < minScalar && Math.Abs(this.Datas[row, col, layer] - this.InvalidValue) > 1e-6)
                                    {
                                        minScalar = this.Datas[row, col, layer];
                                    }

                                    #endregion

                                }
                            }
                        }
                    }
                }
                else
                {
                    for (int layer = 0; layer < this.Nlayers; layer++)
                    {
                        for (int row = 0; row < this.Nrows; row++)
                        {
                            for (int col = 0; col < this.Ncols; col++)
                            {
                                #region 最小值

                                if (this.Datas[row, col, layer] < minScalar && Math.Abs(this.Datas[row, col, layer] - this.InvalidValue) > 1e-6)
                                {
                                    minScalar = this.Datas[row, col, layer];
                                }

                                #endregion
                            }
                        }
                    }
                }

                if ( minScalar == double.MaxValue)
                {
                    minScalar = 0;
                }

                base.MinValue = minScalar;



                return base.MinValue;


                #endregion
            }
        }

        #endregion


        #region 共有方法

        public void SetIBounds(List<int[,]> iBound)
        {
            this._effIBound = iBound;
            //this.ComputeMinMax();
        }

        #endregion


        #region 取得指定数据的辅助方法


        /// <summary>
        /// 取得数据并以指定的存放形式返回  可以返回指定层和所有层的数据
        /// </summary>
        /// <param name="gridCellScalar">存储 所有网格的数据</param>
        /// <returns></returns>
        public bool GetAllGridData(List<double[,]> gridCellScalar)
        {

            try
            {
                if (gridCellScalar == null)
                {
                    gridCellScalar = new List<double[,]>();

                    //return false;
                }
                else
                {
                    gridCellScalar.Clear();
                }

                for (int layer = 0; layer < Nlayers ; layer++)
                {
                    double[,] layerScalar = new double[Nrows ,Ncols ];

                    for (int row = 0; row < this.Nrows ; row++)
                    {
                        for (int col = 0; col < this.Ncols ; col++)
                        {

                            layerScalar[row, col] = this.Datas[row, col, layer];

                        }
                    }

                    gridCellScalar.Add(layerScalar);

                }


                return true;
            }
            catch (Exception)
            {
                System.Windows.Forms.MessageBox.Show("从运行结果产生的数据中提取CellScalar值时出错！");
                return false;
            }

        }


        /// <summary>
        /// 增加新的数据接口
        /// </summary>
        /// <returns></returns>
        public List<double[,]> ToListData()
        {

            List<double[,]> gridCellScalar = new List<double[,]>();


            for (int layer = 0; layer < Nlayers; layer++)
            {
                double[,] layerScalar = new double[Nrows, Ncols];

                for (int row = 0; row < this.Nrows; row++)
                {
                    for (int col = 0; col < this.Ncols; col++)
                    {

                        layerScalar[row, col] = this.Datas[row, col, layer];

                    }
                }

                gridCellScalar.Add(layerScalar);

            }


            return gridCellScalar;
 

        }

        /// <summary>
        /// 将内部数据重置为一个常量
        /// </summary>
        /// <param name="value"></param>
        public void ConstantData(double value)
        {

            if (this.Datas==null)
            {

                return;

            }


            for (int layer = 0; layer < Nlayers; layer++)
            {
              

                for (int row = 0; row < this.Nrows; row++)
                {
                    for (int col = 0; col < this.Ncols; col++)
                    {

                        this.Datas[row, col, layer] = value;


                    }
                }

              

            }

 
        }


       /// <summary>
        /// 更新三维数组数据  同时需要重新计算最大最小值  三维数组的顺序[row,col,layer]
       /// </summary>
       /// <param name="datas"></param>
       public void Update3DArryDatas( double[, ,] datas)
        {

            if (datas ==null )
            {
                return;
            }

            this.Nrows  = datas.GetLength(0);
            this.Ncols  = datas.GetLength(1);
            this.Nlayers  = datas.GetLength(2);


           //更新三维数组
            this._datas = new double[Nrows, Ncols, Nlayers];

            for (int row = 0; row < Nrows; row++)
            {
                for (int col = 0; col < Ncols ; col++)
                {
                    for (int layer = 0; layer < Nlayers ; layer++)
                    {

                        _datas[row, col, layer] = datas[row, col, layer];
                    }
                }
            }


           //更新最大最小值

            //ComputeMinMax();



        
        }



        #endregion


        #region 内部方法

        //改为通过属性现取现算方法
        //protected void ComputeMinMax()
        //{
        //    double minScalar = 0;
        //    double maxScalar = 0;

        //    if (this.Nlayers > 0 && this.Nrows > 0 && this.Ncols > 0)
        //    {
        //        //if (Math.Abs(this.Datas[0, 0, 0] - this.InvalidValue) < 1e-6)
        //        //{
        //            minScalar = double.MaxValue;
        //            maxScalar = double.MinValue;
        //        //}
        //        //else
        //        //{
        //        //    minScalar = this.Datas[0, 0, 0];
        //        //    maxScalar = this.Datas[0, 0, 0];
        //        //}
                
        //    }
           

        //    List<double> scalarMinMax = new List<double>();

        //    for (int layer = 0; layer < this.Nlayers; layer++)
        //    {
        //        for (int row = 0; row < this.Nrows; row++)
        //        {
        //            for (int col = 0; col < this.Ncols; col++)
        //            {

        //                if (this._effIBound != null)
        //                {
        //                    if (this._effIBound[layer][row, col] != 0)
        //                    {
        //                        //当单元有效的时候将影响最大最小值

        //                        #region 最小值

        //                        if (this.Datas[row, col, layer] < minScalar)
        //                        {

        //                            //分别考虑无效值的影响


        //                            if (Math.Abs(this.Datas[row, col, layer] - this.InvalidValue) < 1e-6)//比较两个double值是否相等 很不安全 ！！
        //                            {

        //                            }
        //                            else
        //                            {
        //                                minScalar = this.Datas[row, col, layer];
        //                            }

        //                        }
        //                        #endregion


        //                        #region 最大值
        //                        if (this.Datas[row, col, layer] > maxScalar)
        //                        {

        //                            if (Math.Abs(this.Datas[row, col, layer] - this.InvalidValue) < 1e-6)//比较两个double值是否相等 很不安全 ！！
        //                            {

        //                            }
        //                            else
        //                            {
        //                                maxScalar = this.Datas[row, col, layer];
        //                            }


        //                        }

        //                        #endregion

        //                    }

        //                }
        //                else
        //                {
        //                    //当this._effIBound == null的时候不考虑有效单元对最大最小值的影响

        //                    #region 最小值
                          
        //                    if (this.Datas[row, col, layer] < minScalar)
        //                    {

        //                        //分别考虑无效值的影响


        //                        if (Math.Abs(this.Datas[row, col, layer] - this.InvalidValue) < 1e-6)//比较两个double值是否相等 很不安全 ！！
        //                        {

        //                        }
        //                        else
        //                        {
        //                            minScalar = this.Datas[row, col, layer];
        //                        }

        //                    }

        //                    #endregion

        //                    #region 最大值

        //                    if (this.Datas[row, col, layer] > maxScalar)
        //                    {

        //                        if (Math.Abs(this.Datas[row, col, layer] - this.InvalidValue) < 1e-6)//比较两个double值是否相等 很不安全 ！！
        //                        {

        //                        }
        //                        else
        //                        {
        //                            maxScalar = this.Datas[row, col, layer];
        //                        }


        //                    }

        //                    #endregion

        //                }


        //            }
        //        }
        //    }

        //    if (minScalar ==double .MaxValue ||maxScalar ==double .MinValue )
        //    {
        //        //if (minScalar == double.MaxValue && maxScalar == double.MinValue)
        //        //{
        //            minScalar = 0;
        //            maxScalar = 0;
        //        //}
        //        //else if(minScalar ==double .MaxValue && maxScalar !=double .MinValue )
        //        //{
                
        //        //}
        //        //else if (minScalar == double.MaxValue && maxScalar != double.MinValue)
        //        //{
                
                
        //        //}
                
        //    }

        //    this.MinValue = minScalar;
        //    this.MaxValue = maxScalar;



        //}

        #endregion


    }
}
